package com.TT.poi;

import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.joda.time.DateTime;
import org.junit.Test;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

public class ExcelWrite {

    /**
     * HSSFWorkbook
     * 缺点：最多 65536 行，超出则报错
     * 优点：过程中写入缓存，不操作磁盘，最后一次性写入磁盘，速度快
     *
     * @throws IOException
     */
    @Test
    public void write03() throws IOException {


        //1.创建一个工作簿
        Workbook workbook = new HSSFWorkbook();
        //2.创建一个工作表
        Sheet sheet = workbook.createSheet("excel表名");
        //3.创建一个行
        Row row1 = sheet.createRow(0);
        //4.创建一个单元格
        Cell cell1 = row1.createCell(0);
        cell1.setCellValue("价钱");

        Cell cell2 = row1.createCell(1);
        cell2.setCellValue(666);

        /*=============================================*/


        //第二行
        Row row2 = sheet.createRow(1);
        Cell cell21 = row2.createCell(0);
        cell21.setCellValue("时间");

        Cell cell22 = row2.createCell(1);
        String time = new DateTime().toString("yyyy-MM-dd HH:mm:ss");
        cell22.setCellValue(time);


        //生成一张表（IO流）
        String path = getPath();
        FileOutputStream outputStream = new FileOutputStream(path + "03.xls");

        workbook.write(outputStream);
        //关闭流
        outputStream.close();

        System.out.println("excel生成完毕...");


    }


    /**
     * XSSFWorkbook
     * 缺点：写数据时速度非常慢，非常耗内存，也会发生内存溢出，如100w条
     * 优点：可以写较大的数据，如20w条
     *
     * @throws IOException
     */
    @Test
    public void write07() throws IOException {


        //1.创建一个工作簿
        Workbook workbook = new XSSFWorkbook();
        //2.创建一个工作表
        Sheet sheet = workbook.createSheet("excel表名");
        //3.创建一个行
        Row row1 = sheet.createRow(0);
        //4.创建一个单元格
        Cell cell1 = row1.createCell(0);
        cell1.setCellValue("价钱");

        Cell cell2 = row1.createCell(1);
        cell2.setCellValue(666);

        /*=============================================*/


        //第二行
        Row row2 = sheet.createRow(1);
        Cell cell21 = row2.createCell(0);
        cell21.setCellValue("时间");

        Cell cell22 = row2.createCell(1);
        String time = new DateTime().toString("yyyy-MM-dd HH:mm:ss");
        cell22.setCellValue(time);


        //生成一张表（IO流）
        String path = getPath();
        FileOutputStream outputStream = new FileOutputStream(path + "07.xlsx");

        workbook.write(outputStream);
        //关闭流
        outputStream.close();

        System.out.println("excel生成完毕...");


    }


    /**
     * 测试
     * HSSFWorkbook
     * 缺点：最多 65536 行，超出则报错
     */
    @Test
    public void testWrite03BigData() throws IOException {
        //时间
        long begin = System.currentTimeMillis();

        //创建一个工作簿
        Workbook workbook = new HSSFWorkbook();
        //创建表
        Sheet sheet = workbook.createSheet();
        //写入数据
        for (int rowNum = 0; rowNum < 65536; rowNum++) {
            Row row = sheet.createRow(rowNum);
            for (int cellNum = 0; cellNum < 10; cellNum++) {
                Cell cell = row.createCell(cellNum);
                cell.setCellValue(cellNum);
            }
        }

        FileOutputStream outputStream = new FileOutputStream(getPath() + "03bigdata.xls");

        workbook.write(outputStream);

        outputStream.close();

        long end = System.currentTimeMillis();

        System.out.println((double) (end - begin) / 1000);
    }


    /**
     * XSSFWorkbook
     * 缺点：写数据时速度非常慢，非常耗内存，也会发生内存溢出，如100w条
     * 优点：可以写较大的数据，如20w条
     */
    @Test
    public void testWrite07BigData() throws IOException {
        //时间
        long begin = System.currentTimeMillis();

        //创建一个工作簿
        Workbook workbook = new XSSFWorkbook();
        //创建表
        Sheet sheet = workbook.createSheet();
        //写入数据
        for (int rowNum = 0; rowNum < 65537; rowNum++) {
            Row row = sheet.createRow(rowNum);
            for (int cellNum = 0; cellNum < 10; cellNum++) {
                Cell cell = row.createCell(cellNum);
                cell.setCellValue(cellNum);
            }
        }

        FileOutputStream outputStream = new FileOutputStream(getPath() + "07bigdata.xlsx");

        workbook.write(outputStream);

        outputStream.close();

        long end = System.currentTimeMillis();

        System.out.println((double) (end - begin) / 1000);
    }


    /**
     * SXSSFWorkbook
     * 注意：
     * 过程中会产生临时文件，需要清理临时文件
     * 默认由100条记录被保存在内存中，如果超过这数量，则最前面的数据被写入临时文件
     * 如果想自定义内存中数据的数量，可以使用new SXSSFWorkbook（数量）
     * 解决上面方法的慢速度
     */
    @Test
    public void testWrite07BigDataFast() throws IOException {
        //时间
        long begin = System.currentTimeMillis();

        //创建一个工作簿
        Workbook workbook = new SXSSFWorkbook();
        //创建表
        Sheet sheet = workbook.createSheet();
        //写入数据
        for (int rowNum = 0; rowNum < 65537; rowNum++) {
            Row row = sheet.createRow(rowNum);
            for (int cellNum = 0; cellNum < 10; cellNum++) {
                Cell cell = row.createCell(cellNum);
                cell.setCellValue(cellNum);
            }
        }

        FileOutputStream outputStream = new FileOutputStream(getPath() + "07bigdata.xlsx");

        workbook.write(outputStream);

        outputStream.close();

        //清除临时文件
        ((SXSSFWorkbook)workbook).dispose();

        long end = System.currentTimeMillis();

        System.out.println((double) (end - begin) / 1000);
    }

    /**
     * 获取项目路径
     *
     * @throws IOException
     */
    private String getPath() throws IOException {
        File directory = new File("");
        return directory.getCanonicalPath() + File.separator;
    }


}
